<template>
  <t-card :bordered="false">
    <!-- 搜索 -->
    <custom-search ref="customSearchRef" v-slot="{ params }" @submit="handleInitTable">
      <t-col :span="3">
        <t-form-item label="流程标识" name="key">
          <t-input v-model:value="params.key" placeholder="请输入流程标识" clearable />
        </t-form-item>
      </t-col>
      <t-col :span="3">
        <t-form-item label="流程名称" name="name">
          <t-input v-model:value="params.name" placeholder="请输入流程名称" clearable />
        </t-form-item>
      </t-col>
      <t-col :span="3">
        <t-form-item label="流程分类" name="category">
          <t-select v-model:value="params.category" placeholder="请选择流程分类" clearable filterable
            :options="categoryOptions" />
        </t-form-item>
      </t-col>
    </custom-search>
    <!-- 表格 -->
    <custom-table ref="customTableRef" row-key="id" :columns="columns" :api="modelCRUD.page"
      column-controller-key="BpmModelList">
      <template #topContent>
        <div style="margin-bottom: var(--td-comp-margin-xxl)">
          <t-button 
            v-permission="['bpm:model:create']" 
            @click="handleOpenDialog('create',{
              managerUserIds: [userStore.userInfo.id], // 默认添加当前用户为管理员
              visible: 'true', // 默认可见
              type: 10, // 默认BPMN类型
              formType: 10, // 默认流程表单类型
              iconList: [] as Array<any>, // 默认空图标列表
            })">新增流程</t-button>
        </div>
      </template>
      <template #status="{ row }">
        <t-tag variant="light" :theme="row.status === 1 ? 'success' : 'default'">
          {{ row.status === 1 ? '已部署' : '未部署' }}
        </t-tag>
      </template>
      <template #icon="{ row }">
        <image-viewer :images="[row.icon]" width="80px" height="80px" />
      </template>
      <template #startUserIds="{ row }">
        <span v-if="!row.startUsers || row.startUsers.length === 0">全部可见</span>
        <span v-else-if="row.startUsers.length == 1"> {{ row.startUsers[0].nickname }}</span>
        <span v-else>
          <t-tooltip
              class="box-item"
              effect="dark"
              placement="top"
              :content="row.startUsers.map((user: any) => user.nickname).join('、')"
            >
              {{ row.startUsers[0].nickname }}等 {{ row.startUsers.length }} 人可见
            </t-tooltip>
        </span>
      </template>
      
      <template #deploymentTime="{ row }">
        <span v-if="row.processDefinition">
            {{ dayjs(row.processDefinition?.deploymentTime).format('YYYY-MM-DD HH:mm:ss') }}
          </span>
          <t-tag v-if="row.processDefinition" class="ml-10px">
            v{{ row.processDefinition.version }}
          </t-tag>
          <t-tag v-else type="warning">未部署</t-tag>
          <t-tag
            v-if="row.processDefinition?.suspensionState === 2"
            type="warning"
            class="ml-10px"
          >
            已停用
          </t-tag>
      </template>
      <template #formType="{ row }">
        <t-link v-if="row.formType === 10" theme="primary" @click="handleFormDetail(row)">
          {{ row.formName }}
        </t-link>
        <t-link v-else-if="row.formType === 20" theme="primary" @click="handleFormDetail(row)">
          {{ row.formCustomCreatePath }}
        </t-link>
        <span v-else>暂无表单</span>
      </template>
      <template #operation="{ row }">
        <t-space break-line>
          <t-link v-permission="['bpm:model:update']" theme="primary" @click="handleOpenDialog('update', { id: row.id })" :disabled="!isManagerUser(row)">
            编辑
          </t-link>
          <t-link v-permission="['bpm:model:design']" theme="primary" @click="handleDesign(row)" :disabled="!isManagerUser(row)">
            设计
          </t-link>
          <t-popconfirm content="是否部署该流程！！" @confirm="handleDeploy(row)">
            <t-link v-permission="['bpm:model:deploy']" theme="primary" :disabled="!isManagerUser(row)" >
            发布
          </t-link>
          </t-popconfirm>
          <t-dropdown  @click="(data) => clickHandler(data, row)">
            <t-link theme="primary">更多</t-link>
            <template #dropdown>
              <t-dropdown-menu>
                <t-dropdown-item command="handleDefinitionList" v-permission="['bpm:process-definition:query']" :disabled="!isManagerUser(row)">
                  历史
                </t-dropdown-item>
                <t-dropdown-item command="handleChangeState" v-permission="['bpm:model:update']" :disabled="!isManagerUser(row)">
                  {{ row.processDefinition?.suspensionState === 1 ? '停用' : '启用' }}
                </t-dropdown-item>
                <t-dropdown-item type="danger" command="handleDelete" v-permission="['bpm:model:delete']" :disabled="!isManagerUser(row)">
                  删除
                </t-dropdown-item>

              </t-dropdown-menu>
            </template>
          </t-dropdown>
          
        </t-space>
      </template>
    </custom-table>
    <!-- 对话框 -->
    <custom-dialog ref="customDialogRef" v-slot="{ formData, readonly }" :api-map="modelCRUD" :on-before-set-data="handleDialogSetData" header="*流程模型" @request-success="handleDialogRequestSuccess">
      <t-form-item label="流程标识" name="key" :rules="[{ required: true, message: '流程标识不能为空', trigger: 'blur' }]">
        <t-input v-model:value="formData.key" :readonly="!!formData.id" placeholder="请输入流程标识" />
        <t-tooltip
          v-if="!formData.id"
          content="新建后，流程标识不可修改！"
          placement="top"
        >
          <t-icon name="help-circle" style="margin-left: 5px" />
        </t-tooltip>
        <t-tooltip v-else content="流程标识不可修改！" placement="top">
          <t-icon name="help-circle" style="margin-left: 5px" />
        </t-tooltip>
      </t-form-item>
      <t-form-item label="流程名称" name="name" :rules="[{ required: true, message: '流程名称不能为空', trigger: 'blur' }]">
        <t-input v-model:value="formData.name" :readonly="!!formData.id" clearable placeholder="请输入流程名称" />
      </t-form-item>
      <t-form-item label="流程分类" name="category" :rules="[{ required: true, message: '流程分类不能为空' }]">
        <t-select v-model:value="formData.category" :readonly="readonly" placeholder="请选择流程分类" clearable filterable
          :options="categoryOptions" />
      </t-form-item>
      <t-form-item label="流程图标" name="icon" :rules="[{ required: true, message: '流程图标不能为空', trigger: 'blur' }]">
        <upload 
          v-model:files="formData.iconList" 
          accept="image/*" 
          theme="image" 
          :disabled="readonly"
          @change="
            (value) => {
              formData.icon = value[0]?.url;
            }
          "
        />
      </t-form-item>
      <t-form-item label="流程描述" name="description">
        <t-textarea v-model:value="formData.description" :readonly="readonly" placeholder="请输入备注" />
      </t-form-item>
      <t-form-item label="流程类型" name="type" :rules="[{ required: true, message: '流程类型不能为空', trigger: 'blur' }]">
        <t-radio-group v-model:value="formData.type">
          <t-radio v-for="dict in dictionaryStore.get('bpm_model_type','number')" :key="dict.value" :value="dict.value">
            {{ dict.label }}
          </t-radio>
        </t-radio-group>
      </t-form-item>
      <t-form-item label="表单类型" name="formType" :rules="[{ required: true, message: '表单类型不能为空', trigger: 'blur' }]">
        <t-radio-group v-model:value="formData.formType">
          <t-radio v-for="dict in dictionaryStore.get('bpm_model_form_type','number')" :key="dict.value" :value="dict.value">
            {{ dict.label }}
          </t-radio>
        </t-radio-group>
      </t-form-item>
      <t-form-item v-if="formData.formType === 10" label="流程表单" name="formId" :rules="[{ required: true, message: '流程表单不能为空' }]">
        <t-select v-model:value="formData.formId" clearable placeholder="请选择流程表单"
          :options="formOptions" />
      </t-form-item>
      <t-form-item v-if="formData.formType === 20" label="表单提交路由" name="formCustomCreatePath" :rules="[{ required: true, message: '表单提交路由不能为空', trigger: 'blur' }]">
        <t-input v-model:value="formData.formCustomCreatePath" placeholder="请输入表单提交路由" style="width: 330px" />
        <t-tooltip content="自定义表单的提交路径，使用 Vue 的路由地址，例如说：bpm/oa/leave/create.vue" placement="top">
          <t-icon name="help-circle" style="margin-left: 5px" />
        </t-tooltip>
      </t-form-item>
      <t-form-item v-if="formData.formType === 20" label="表单查看地址" name="formCustomViewPath" :rules="[{ required: true, message: '表单查看地址不能为空', trigger: 'blur' }]">
        <t-input v-model:value="formData.formCustomViewPath" placeholder="请输入表单查看的组件地址" style="width: 330px" />
        <t-tooltip content="自定义表单的查看组件地址，使用 Vue 的组件地址，例如说：bpm/oa/leave/detail.vue" placement="top">
          <t-icon name="help-circle" style="margin-left: 5px" />
        </t-tooltip>
      </t-form-item>
      <t-form-item label="是否可见" name="visible" :rules="[{ required: true, message: '是否可见不能为空', trigger: 'blur' }]">
        <t-radio-group v-model:value="formData.visible">
          <t-radio v-for="dict in dictionaryStore.get('infra_boolean_string')" :key="dict.value" :value="dict.value">
            {{ dict.label }}
          </t-radio>
        </t-radio-group>
      </t-form-item>
      <t-form-item label="谁可以发起" name="startUserIds">
        <t-select v-model:value="formData.startUserIds" multiple :keys="{ value: 'id', label: 'nickname' }" placeholder="请选择可发起人，默认（不选择）则所有人都可以发起"
          :options="simpleUserList" />
      </t-form-item>
      <t-form-item label="流程管理员" name="managerUserIds" :rules="[{ required: true, message: '流程管理员不能为空', trigger: 'blur' }]">
        <t-select v-model:value="formData.managerUserIds" multiple :keys="{ value: 'id', label: 'nickname' }" placeholder="请选择流程管理员"
          :options="simpleUserList" />
      </t-form-item>
    </custom-dialog>

    <!-- 弹窗：表单详情 -->
    <t-dialog header="表单详情" v-model:visible="formDetailVisible" width="800">
      <div v-if="formDetailPreview.rule ">
        <form-create
          v-model:value="formDetailPreview.formData"
          :rule="formDetailPreview.rule"
          :option="formDetailPreview.option"
        />
      </div>
      <div v-else>暂无表单数据</div>
    </t-dialog>
  </t-card>
</template>

<script lang="ts">
export default {
  name: 'BpmModel',
};
</script>

<script lang="ts" setup>
import { onMounted, ref, useTemplateRef } from 'vue';
import { DialogPlugin, MessagePlugin, TableCol } from 'tdesign-vue-next';
import { useRouter } from 'vue-router';
import dayjs from 'dayjs';
import FormCreate from '@/components/FormCreate/index.vue';

import { modelCRUD, deployModel, updateModelState } from '@/api/bpm/model';
import {  getCategorySimpleList } from '@/api/bpm/category';
import { formCRUD, getFormSimpleList } from '@/api/bpm/form';
import { getSimpleUserList } from '@/api/system/user';
import CustomDialog from '@/components/custom/dialog/index.vue';
import CustomSearch from '@/components/custom/search/index.vue';
import CustomTable from '@/components/custom/table/index.vue';
import ImageViewer from '@/components/image-viewer/index.vue';
import Upload from '@/components/upload/index.vue';
import { useDictionaryStore, useUserStore } from '@/store';
// 字典仓库
const dictionaryStore = useDictionaryStore();
// 自定义搜索ref
const customSearchRef = useTemplateRef('customSearchRef');
// 自定义表格ref
const customTableRef = useTemplateRef('customTableRef');
// 自定义对话框ref
const customDialogRef = useTemplateRef('customDialogRef');

// 流程分类选项
const categoryOptions = ref([]);
// 流程表单选项
const formOptions = ref([]);


// 用户选项
const userOptions = ref([]);

interface FormField {
  field: string;
  title: string;
  type: string;
  value?: any;
  props?: {
    placeholder?: string;
    options?: Array<{ label: string; value: any }>;
  };
  validate?: any[];
}

// 表单详情
const formDetailVisible = ref(false);
const formDetailPreview = ref<{
  rule: FormField[];
  formData: Record<string, any>;
  option: Record<string, any>;
}>({
  rule: [],
  formData: {},
  option: {
    submitBtn: false,
    form: {
      disabled: true
    }
  },
});

// columns
const columns: TableCol[] = [
  { colKey: 'name', title: '流程名称' },
  { colKey: 'icon', title: '流程图标' },
  { colKey: 'startUserIds', title: '可见范围' },
  { colKey: 'categoryName', title: '流程分类' },
  { colKey: 'formType', title: '表单信息' },
  { colKey: 'deploymentTime', title: '最后发布', width: 180 },
  { colKey: 'operation', title: '操作', width: 200 },
];

// 处理初始化表格
const handleInitTable = () => {
  customTableRef.value.initTable(customSearchRef.value.params);
};

// 处理刷新表格
const handleRefreshTable = () => {
  customTableRef.value.refreshTable();
};

// 处理打开对话框
const handleOpenDialog = async (mode: 'create' | 'update', params?: Record<string, any>) => {
  customDialogRef.value.open(mode, params);
};


// 处理设计
const handleDesign = (row: Record<string, any>) => {
  router.push(`/approve/design?id=${row.id}`);
};
// 处理对话框请求成功
const handleDialogRequestSuccess = (result: Record<string, any>) => {
  if (result.mode === 'create') handleInitTable();
  if (result.mode === 'update') handleRefreshTable();
};
// 处理部署
const handleDeploy = async (row: Record<string, any>) => {
  await deployModel( row.id );
  MessagePlugin.success('部署成功');
  handleRefreshTable();
};
// 更多
const clickHandler = (data: any, row: any) => {
  const { command } = data
  switch (command) {
    case 'handleDefinitionList':
      handleDefinitionList(row)
      break
    case 'handleDelete':
      handleDelete({id: row.id})
      break
    case 'handleChangeState':
      handleChangeState(row)
      break
    default:
      break
  }

}
/** 跳转到指定流程定义列表 */
const handleDefinitionList = (row: any) => {
  router.push({
    name: 'ApproveProcessDefinition',
    query: {
      key: row.key
    }
  })
}
/** 更新状态操作 */
const handleChangeState = async (row: any) => {
  const state = row.processDefinition?.suspensionState
  const newState = state === 1 ? 2 : 1
  try {
    // 修改状态的二次确认
    const id = row.id
    const statusState = state === 1 ? '停用' : '启用'
    const content = '是否确认' + statusState + '流程名字为"' + row.name + '"的数据项?'
    const params = {
      id,
      state
    }

    const confirmDia = DialogPlugin({
      body: content,
      confirmBtn: '确定',
      cancelBtn: '取消',
      onConfirm: async () => {
        // 发起修改状态
        await updateModelState(params)
        MessagePlugin.success(statusState + '成功')
        confirmDia.hide()
        // 刷新列表
        await handleRefreshTable()
      },
      onClose: () => {
        // 用户点击"取消"或关闭弹窗时的操作
        confirmDia.hide()
      },
    });
  } catch {}
  
}
// 处理删除
const handleDelete = (params: Record<string, any>) => {
  modelCRUD
    .delete(params)
    .then(() => {
      MessagePlugin.success('删除成功');
      handleRefreshTable();
    })
    .catch(({ message }) => {
      MessagePlugin.error(message);
    });
};

// 获取用户选项
const getUserOptions = async () => {
  try {
    const res = await getSimpleUserList();
    userOptions.value = res.map((item: any) => ({
      label: item.nickname,
      value: item.id,
    }));
  } catch (error) {
    console.error('获取用户列表失败:', error);
    MessagePlugin.error('获取用户列表失败');
  }
};

// 获取流程分类选项
const getCategoryOptions = async () => {
  try {
    const res = await getCategorySimpleList();
    categoryOptions.value = res.map((item: any) => ({
      label: item.name,
      value: item.code,
    }));
  } catch (error) {
    console.error('获取流程分类失败:', error);
    MessagePlugin.error('获取流程分类失败');
  }
};

// 获取流程表单选项
const getFormOptions = async () => {
  try {
    const res = await getFormSimpleList();
    formOptions.value = res.map((item: any) => ({
      label: item.name,
      value: item.id,
    }));
  } catch (error) {
    console.error('获取流程表单失败:', error);
    MessagePlugin.error('获取流程表单失败');
  }
};

// 精简用户列表
const simpleUserList = ref([]);
// 处理获取精简用户列表
const handleGetSimpleUserList = () => {
  getSimpleUserList().then((data) => {
    simpleUserList.value = data;
  });
};
handleGetSimpleUserList();

const router = useRouter();

// 获取表单组件类型
const getFormComponent = (type: string) => {
  const componentMap: Record<string, string> = {
    input: 't-input',
    textarea: 't-textarea',
    select: 't-select',
    radio: 't-radio-group',
    checkbox: 't-checkbox-group',
    date: 't-date-picker',
    time: 't-time-picker',
    number: 't-input-number',
    switch: 't-switch',
  };
  return componentMap[type] || 't-input';
};

// 处理表单详情
const handleFormDetail = async (row: Record<string, any>) => {
  if (row.formType === 10) {
    try {
      // 设置表单
      const data = await formCRUD.get({ id: row.formId });
      
      // 解析字段配置
      let fields: FormField[] = [];
      let conf = {};
      
      try {
        // 解析配置
        conf = JSON.parse(data.conf || '{}');
        
        // 解析字段 - 注意：fields 是字符串数组，每个元素都是 JSON 字符串
        fields = data.fields.map((fieldStr: string) => {
          try {
            const field = JSON.parse(fieldStr);
            return {
              field: field.field || '',
              title: field.title || '',
              type: field.type || 'input',
              value: field.value,
              props: {
                placeholder: `请输入${field.title || ''}`,
                ...field.props,
                // 添加必填验证
                required: field.$required
              },
              validate: field.$required ? [{ required: true, message: `${field.title}必填` }] : undefined
            };
          } catch (fieldError) {
            console.error('解析字段配置失败:', fieldError);
            return null;
          }
        }).filter(Boolean) as FormField[];
      } catch (parseError) {
        console.error('解析表单配置失败:', parseError);
        fields = [];
        conf = {};
      }

      // 更新表单预览数据
      formDetailPreview.value = {
        rule: fields,
        formData: {},
        option: {
          ...conf,
          form: {
            ...(conf as any).form,
            disabled: true
          }
        }
      };

      // 弹窗打开
      formDetailVisible.value = true;
    } catch (error) {
      console.error('获取表单数据失败:', error);
      MessagePlugin.error('获取表单数据失败');
    }
  } else {
    await router.push({
      path: row.formCustomCreatePath
    });
  }
};
// 处理对话框设置数据
const handleDialogSetData = (params: Record<string, any>) => {
  params.visible = params.visible?'true':'false'
  
};
// 导入 userStore
const userStore = useUserStore();
/** 判断是否可以操作 */
const isManagerUser = (row: any) => {
  const userId = userStore.userInfo.id
  return row.managerUserIds && row.managerUserIds.includes(userId)
}
onMounted(() => {
  handleInitTable();
  getCategoryOptions();
  getFormOptions();
  getUserOptions();
});
</script> 